package com.sj.tensquare.web.controller;

import com.sj.common.exception.BizCodeEnume;
import com.sj.common.utils.R;
import com.sj.tensquare.web.constant.AuthServerConstant;
import com.sj.tensquare.web.feign.ThirdPartFeignService;
import com.sj.tensquare.web.feign.UserFeign;
import com.sj.tensquare.web.vo.UserRegistVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Valid;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author sj
 * @date 2020/12/9 - 11:26
 */
@Controller
@Slf4j
public class LoginController {
    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserFeign userFeign;

    @Autowired
    private ThirdPartFeignService thirdPartFeignService;

    @Autowired
    StringRedisTemplate redisTemplate;

    //todo 注册用户
    @PostMapping("/userlogin")
    public String loginUser(@Valid UserRegistVo registVo, BindingResult result, RedirectAttributes attributes){
        logger.debug("注册信息：",registVo);
        if (result.hasErrors()){
            //校验出错，转发回注册页面
            Map<String, String> error = result.getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
            attributes.addFlashAttribute("error",error);
            return "redirect:/register.html";
        }
        return "注册成功";
    }

    @GetMapping("/login.html")
    public String loginPage(@RequestParam("redirect_url") String url, Model model){
        model.addAttribute("url",url);
        return "login";
    }


    @PostMapping("/login")
    public String login(String username, String password, Model model){
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登陆数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);//执行登陆的方法，如果没有异常就说明ok
            //todo 发布文章 逻辑得处理一下
            return "articles-list";
        }catch (UnknownAccountException e){
            model.addAttribute("msg","用户名错误");
            return "login";
        }catch (IncorrectCredentialsException e){
            model.addAttribute("msg","密码错误");
            return "login";
        }
    }

    @GetMapping("/smsCode")
    @ResponseBody
    public R smsCode(@RequestParam("phone")String phone){
        //todo 1.接口防刷

        String redisCode = redisTemplate.opsForValue().get(AuthServerConstant.SMS_CODE_CACHE_PREFIX + phone);
        //从缓存中取验证码的值 做判断
        if (!StringUtils.isEmpty(redisCode)){
            long s = Long.parseLong(redisCode.split("_")[1]);
            if (System.currentTimeMillis()-s < 60000){
                //60秒内不能再发
                return R.error(BizCodeEnume.SMS_CODE_EXCEPTION.getCode(),BizCodeEnume.SMS_CODE_EXCEPTION.getMsg());
            }
        }


        //2.验证码的再次依赖。redis key-phone value-code sms:code:135xxxxx -> 123456
        String code = UUID.randomUUID().toString().substring(0, 5)+"_"+System.currentTimeMillis();

        //redis缓存验证码，防止同一个phone在60秒内再次发生验证码
        redisTemplate.opsForValue().set(AuthServerConstant.SMS_CODE_CACHE_PREFIX+phone,code,10, TimeUnit.MINUTES);

        thirdPartFeignService.sendCode(phone,code.substring(0,5));
        return new R().ok();
    }
}
